package com.douwong.student.socket;


import android.content.Context;
import android.util.Log;

import com.douwong.student.application.BaseApplication;
import com.douwong.student.contant.Config;
import com.douwong.student.enums.E_CommandType;
import com.douwong.student.enums.E_Destination;
import com.douwong.student.factory.ThreadFactory;
import com.douwong.student.model.TcpPacket;
import com.douwong.student.utils.JsonUtils;
import com.douwong.student.utils.LogUtils;
import com.douwong.student.utils.ToastUtils;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetAddress;
import java.net.InetSocketAddress;

/**
 * @autor yichao
 * @time 2016/9/2316:49
 * @des
 */
public class LTPServer implements IConnectManager {
    private static final String TAG = LTPServer.class.getSimpleName();
    private IoConnector acceptor;
    private static LTPServer mLTPServer;
    private IoSession mIoSession;//连接session
    private  Context mContext;
    private final MessageQueue.MqHandler mHandler;

    public static LTPServer createInstance(Context context){
        if (mLTPServer==null){
            synchronized (LTPServer.class){
                if (mLTPServer==null){
                    mLTPServer=new LTPServer(context);
                }
            }
        }
        return mLTPServer;
    }
    private LTPServer(Context context){
        this.mContext=context;

       mHandler = MessageQueue.getInstance(mContext).getLwHandler();
    }

    @Override
    public void startWork() {
        try {
            //acceptor置空
            if(acceptor!=null){
                acceptor.dispose();
                acceptor=null;
            }
            //sessiona置空
            if(mIoSession!=null){
                mIoSession.close(false);
                mIoSession=null;
            }
     /*       InetSocketAddress address = new InetSocketAddress(Config.serviceIp,
                     Config.servicePort);*/
            InetAddress byName = InetAddress.getByName(Config.serviceDomain);
            InetSocketAddress address = new InetSocketAddress(byName,
                    Config.servicePort);
            Log.i(TAG, "准备连接");
            ConnectFuture connectFuture = getAcceptor().connect(address);
            connectFuture.awaitUninterruptibly();
            if (connectFuture.isDone()){//连接完成
                if (!connectFuture.isConnected()){//未连接
                    //重连接
                    TCPReconnect.getInstance().reconnectTcp(mContext);
                    LogUtils.i(TAG,"连接失败");
                }else {
                    //连接成功
                    TCPReconnect.reconnectCount=0;
                    LogUtils.i(TAG,"连接成功");
                }
            }else {
                //连接未完成
                //重连接
                TCPReconnect.getInstance().reconnectTcp(mContext);
            }
        }catch (Exception e){
            e.printStackTrace();
            LogUtils.i(TAG,"startWork ： err"+e.toString());
           // ToastUtils.make(UIUtils.getResources().getString(R.string.));
        }
    }

    @Override
    public void endWork() {
        LogUtils.i(TAG,"调用关闭连接方法");

        try {
            if (mIoSession != null && mIoSession.isConnected()) {
                mIoSession.close(false);
                mIoSession=null;
            }

            if (acceptor != null) {
                acceptor.dispose();
                acceptor = null;
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            ToastUtils.makeText(BaseApplication.mContext,"断开连接失败");
        }
    }
    /**
     * 得到 minad的连接
     * @return
     */
    public IoConnector getAcceptor() {

        if (acceptor == null) {
            acceptor = new NioSocketConnector();
            acceptor.setConnectTimeoutMillis(1000*20);//连接超时
            DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
            chain.addLast("logger", new LoggingFilter());
            chain.addLast("codec", new ProtocolCodecFilter(new TcpCodeFilter()));
            IoSessionConfig config = acceptor.getSessionConfig();
            // 通道空闲发送心跳包
          /*  config.setIdleTime(IdleStatus.BOTH_IDLE,
                    5);*/
            acceptor.setHandler(new LTCHander());
        }
        return acceptor;
    }

  public void   sendMsg(Object obj,E_CommandType commandType,E_Destination to,int [] recevice){

      // TODO Auto-generated method stub


      TcpPacket packet=new TcpPacket(obj,commandType,E_Destination.student,to,BaseApplication.sUserBean.getUserbean().getId(),recevice);
      sendMsg(packet);
    }
    public void sendMsg(final TcpPacket tcpPacket){

        if (mIoSession == null || !mIoSession.isConnected()) {
            // Toast.makeText(context, "请先连接教师端！", Toast.LENGTH_LONG).show();
            return;
        }
        ThreadFactory.getNormalPool().execute(new Runnable() {
            @Override
            public void run() {
                mIoSession.write(tcpPacket);
            }
        });
    }
public void sendHeartMsg(final Object object ){
    ThreadFactory.getCheckHeartPool().execute(new Runnable() {
        @Override
        public void run() {
             mIoSession.write(object);

        }
    });

}
    /**
     * 长连接的操作
     */
    public class LTCHander implements IoHandler {


        @Override
        public void exceptionCaught(IoSession sesssion, Throwable arg1)
                throws Exception {
            Log.w(TAG, "出现异常  ： " + arg1.getMessage());
            endWork();
            arg1.printStackTrace();
        }

        // 接收到消息
        @Override
        public void messageReceived(IoSession sesssion, Object message)
                throws Exception {
            if (message instanceof byte[] && ((byte[])message).length==1){
                BaseApplication.currentHeartTime=System.currentTimeMillis();
                Log.i(TAG, "收到消息 心跳消息 ： " + 1);
                return;
            }
            String msg = message.toString();
            Log.i(TAG, "收到消息  ： " + msg);
            TcpPacket  model= JsonUtils.deserialize(msg,TcpPacket.class);
            if(model==null){
                LogUtils.i(TAG,"解析为空");
                throw new Exception("messageReceived model is null....");
            }
            if(mHandler!=null){
                mHandler.obtainMessage(0, model).sendToTarget();
            }
          // LogUtils.i(TAG, model.commandType==E_CommandType.studentGetTeacher);
           /* TcpPacket model = JsonUtils.parseObjectFromGosn(msg, TcpPacket.class);

            */

        }

        // 发送消息传成功
        @Override
        public void messageSent(IoSession sesssion, Object message)
                throws Exception {
            Log.i(TAG, "发送消息 ："+message.toString());
        }
        // 连接断开
        @Override
        public void sessionClosed(IoSession sesssion) throws Exception {
            Log.i(TAG, " _______________________sessionClosed+++++++++++++++" );

         //   FileUtils.writeFile( (DateTools.getCoverDate()+"sessionClosed").getBytes(), Environment.getExternalStorageDirectory().getAbsolutePath(), "sessionClosed.txt");
            BaseApplication.isLoginClass=false;
            endWork();
            TCPReconnect.getInstance().reconnectTcp(mContext);

            Log.i(TAG, "连接关闭");

        }

        @Override
        public void sessionCreated(IoSession sesssion) throws Exception {
            mIoSession = sesssion;
            Log.i(TAG, "..................................sessionCreated............");
        }

        @Override
        public void sessionIdle(IoSession sesssion, IdleStatus arg1)
                throws Exception {
            Log.i(TAG, "....................................sessionIdle............");
        }

        @Override
        public void sessionOpened(IoSession sesssion) throws Exception {
            Log.i(TAG, "sessionOpened............" + Thread.currentThread().getName());
            //登录本地服务器
            //  sendMsg(BaseApplication.sStudentOnline,E_CommandType.studentGetTeacher);
            sendMsg(BaseApplication.sStudentOnline,E_CommandType.studentGetTeacher,E_Destination.server,new int[]{0});

        }
    }

}
